﻿///////////////////////////////////////////////////////////////////////////////
// File Name: EditSkin.cpp 
// Purpose: EditSkin.h 实现文件
// Author: 张东斌、ChongyangLee
// E_Mail: malutianshi7905@sina.com; ChongyangLee@hotmail.com
// History: 
// 2009/10/03 Mod 边界绘制条件 WS_EX_CLIENTEDGE
// 2009/10/03 Mod 边界绘制 DrawImageBorder
// 2009/10/15 Mod 将是否有边界和滚动条判断移至父类
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "skinedit.h"
#include "EditSkin.h"

CSkinEdit::CSkinEdit(void)
{
	//m_pEditSkin = GetSkin().GetEditSkin();
}

CSkinEdit::~CSkinEdit(void)
{
	if(m_bHScroll || m_bVScroll)
		UninitializeSB(m_hWnd);
	HookWindow( (HWND)NULL);
}
BOOL CSkinEdit::LoadSkin()
{
    CAutoEnableSkin a(m_bEnableSkin);
	m_pEditSkin = GetSkin().GetEditSkin();
	m_pSkinScrollBar = GetSkin().GetScrollBarSkin();
    if (!m_pEditSkin || !m_pSkinScrollBar)
    {
        return FALSE;
    }
	SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
    return TRUE;
}
BOOL CSkinEdit::InstallSkin(HWND hWnd)
{
    if (!hWnd || !LoadSkin())
    {
        return FALSE;
    }
	HookWindow( (HWND)NULL);

	int r = HookWindow( hWnd );

	if(m_pEditSkin == NULL)
		m_pEditSkin = GetSkin().GetEditSkin();

	GetBorderAndScroll();

	if(m_bHScroll || m_bVScroll)
		InitializeSB(m_hWnd);

	SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0,  SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
    return TRUE;
}

/*****************************************
* 函数名 : OnNcHitTest
* 功能	 : 当鼠标移动时调用此函数 
*******************************************/
UINT CSkinEdit::OnNcHitTest( const CPoint& point )
{
	CRect rtWindow;
	CRect rtClient;

	int nHHeight = GetSystemMetrics(SM_CYHSCROLL);
	int nVWidth = GetSystemMetrics(SM_CXVSCROLL);
	GetWindowRect(&rtWindow);
	GetClientRect(&rtClient);
	ClientToScreen(&rtClient);

	if(rtClient.PtInRect(point))
		return HTCLIENT;
	if(m_bVScroll)
	{
		if(m_bLeftScroll)
			m_rtVScroll = CRect(rtClient.left - nVWidth,rtClient.top,rtClient.left,rtClient.bottom);
		else
			m_rtVScroll = CRect(rtClient.right,rtClient.top,rtClient.right + nVWidth,rtClient.bottom);

		if(m_rtVScroll.PtInRect(point))
			return HTVSCROLL;
	}

	if(m_bHScroll)
	{
		m_rtHScroll = CRect(rtClient.left,rtClient.bottom,rtClient.right,rtClient.bottom + nHHeight);

		if(m_rtHScroll.PtInRect(point))
			return HTHSCROLL;
	}
	return HTNOWHERE;
}

/******************************************
* 函数名 : OnNcPaint
* 功能	 : 当非客户需要重画时调用 
*******************************************/
void CSkinEdit::OnNcPaint(HRGN rgn)
{
#ifdef _WIN64
	LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE);
	LONG_PTR exstyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
#else
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
	DWORD exstyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
#endif
	m_bHScroll		= style & WS_HSCROLL;
	m_bVScroll		= style & WS_VSCROLL;
	m_bLeftScroll	= exstyle & WS_EX_LEFTSCROLLBAR;

	CWnd *pWnd = CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(pWnd);
	pDC = pWnd->GetWindowDC();
	CRect rtWindow;
	pWnd->GetWindowRect( rtWindow );
	
	CRect rtClient;
	GetClientRect(&rtClient);
	ClientToScreen(&rtClient);
	rtClient.OffsetRect(-rtWindow.left,-rtWindow.top);
	rtWindow.OffsetRect(-rtWindow.left,-rtWindow.top);

	if(m_bHScroll)
		DrawHScrollBar(pDC);
	if(m_bVScroll)
		DrawVScrollBar(pDC);

	if(m_bBorder)
	{
		if(!m_pEditSkin->DrawImageBorder(pDC, rtWindow, m_pEditSkin->m_imageBorder))
			pDC->Draw3dRect(rtWindow,::GetSysColor(COLOR_BTNFACE),::GetSysColor(COLOR_BTNFACE));
	}

	if(m_bHScroll && m_bVScroll)
	{
		CRect rtSizing;
		if(m_bLeftScroll)
		{
			rtSizing = CRect(rtClient.right - GetSystemMetrics(SM_CXVSCROLL), rtClient.bottom,rtClient.right,rtClient.bottom + GetSystemMetrics(SM_CYHSCROLL));
		}
		else
		{
			rtSizing = CRect(rtClient.right, rtClient.bottom,rtClient.right + GetSystemMetrics(SM_CXVSCROLL),
				rtClient.bottom + GetSystemMetrics(SM_CYHSCROLL));
		}
		m_pSkinScrollBar->DrawSizing(pDC,rtSizing);
	}
}


/******************************************
* 函数名 : OnNcLButtonDown
* 功能	 : 非客户区按下鼠标左键 
*******************************************/
void CSkinEdit::OnNcLButtonDown( UINT nHitTest, const CPoint& point )
{
	switch(nHitTest)
	{
	case HTHSCROLL:
		TrackScrollBar(SB_HORZ,point);
		break;
	case HTVSCROLL:
		TrackScrollBar(SB_VERT,point);
		break;
	default:
		Default();
		break;
	}
}
/******************************************
* 函数名 : OnNcLButtonDblClk
* 功能	 : 非客户区双击鼠标左键 
*******************************************/
void CSkinEdit::OnNcLButtonDblClk( UINT nHitTest, const CPoint& point )
{
	if(nHitTest == HTHSCROLL)
	{
		TrackScrollBar(SB_HORZ,point);
	}
	else if(nHitTest == HTVSCROLL)
	{
		TrackScrollBar(SB_VERT,point);
	//	SendMessage( m_hWnd, WM_SYSCOMMAND, (WPARAM)SC_VSCROLL, MAKELPARAM(point.x,point.y) );
	}
	else
		Default();
}
/******************************************
* 函数名 : OnNcCalcSize
* 功能	 : 根据窗口大小计算客户区大小 
*******************************************/
void CSkinEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
	/*return*/ OnNcCalcSizeSB(bCalcValidRects, lpncsp);	
}

void CSkinEdit::OnMouseMove( UINT nFlags, const CPoint& point )
{
	Default();

	if(m_nHArrowLeftState != keScrollNormal ||m_nHArrowRightState != keScrollNormal|| m_nHThumbState != keScrollNormal 
		|| m_nVArrowTopState != keScrollNormal || m_nVArrowBottomState != keScrollNormal|| m_nVThumbState != keScrollNormal)
	{
		CWindowDC dc(CWnd::FromHandle(m_hWnd));

		m_nVArrowTopState = keScrollNormal;
		m_nVArrowBottomState = keScrollNormal;
		m_nVThumbState = keScrollNormal;
		if(m_bVScroll)		
			DrawVScrollBar(&dc);

		m_nHArrowLeftState = keScrollNormal;
		m_nHArrowRightState = keScrollNormal;
		m_nHThumbState = keScrollNormal;
		if(m_bHScroll)
			DrawHScrollBar(&dc);
	}
}
/******************************************
* 函数名 : OnNcMouseMove
* 功能	 : 非客户区鼠标移动 
*******************************************/
void CSkinEdit::OnNcMouseMove( UINT nHitTest, CPoint point )
{
	CWindowDC dc(CWnd::FromHandle(m_hWnd));
	switch(nHitTest)
	{
	case HTHSCROLL:
		{
			int xoffset = 0, yoffset = 0;
			CRect rtClient,rtWindow;
			GetClientRect(&rtClient);
			ClientToScreen(&rtClient);
			GetWindowRect(&rtWindow);

			xoffset = rtClient.left - rtWindow.left;
			yoffset = rtClient.top - rtWindow.top;
			::ScreenToClient(m_hWnd, &point );
			point.x += xoffset;
			point.y += yoffset;
			SCROLL_HITTEST test = ScrollHitTest(SB_HORZ,point,FALSE);

			if(test == SCROLL_TOP_ARROW)
			{
				m_nHArrowLeftState = keScrollHover;
				m_nHArrowRightState = keScrollNormal;
				m_nHThumbState = keScrollNormal;
				DrawHScrollBar(&dc);
			}
			else if(test == SCROLL_BOTTOM_ARROW)
			{
				m_nHArrowLeftState = keScrollNormal;
				m_nHArrowRightState = keScrollHover;
				m_nHThumbState = keScrollNormal;
				DrawHScrollBar(&dc);
			}
			else if(test == SCROLL_THUMB)
			{
				m_nHArrowLeftState = keScrollNormal;
				m_nHArrowRightState = keScrollNormal;
				m_nHThumbState = keScrollHover;
				DrawHScrollBar(&dc);
			}
			else
			{
				m_nHArrowLeftState = keScrollNormal;
				m_nHArrowRightState = keScrollNormal;
				m_nHThumbState = keScrollNormal;
				DrawHScrollBar(&dc);
			}

			m_nVArrowTopState = keScrollNormal;
			m_nVArrowBottomState = keScrollNormal;
			m_nVThumbState = keScrollNormal;
			if(m_bVScroll)		
				DrawVScrollBar(&dc);
		}
		break;
	case HTVSCROLL:
		{
			int xoffset = 0, yoffset = 0;
			CRect rtClient,rtWindow;
			GetClientRect(&rtClient);
			ClientToScreen(&rtClient);
			GetWindowRect(&rtWindow);

			xoffset = rtClient.left - rtWindow.left;
			yoffset = rtClient.top - rtWindow.top;
			::ScreenToClient(m_hWnd, &point );
			point.x += xoffset;
			point.y += yoffset;
			SCROLL_HITTEST test = ScrollHitTest(SB_VERT,point,FALSE);

			if(test == SCROLL_TOP_ARROW)
			{
				m_nVArrowTopState = keScrollHover;
				m_nVArrowBottomState = keScrollNormal;
				m_nVThumbState = keScrollNormal;
				DrawVScrollBar(&dc);
			}
			else if(test == SCROLL_BOTTOM_ARROW)
			{
				m_nVArrowTopState = keScrollNormal;
				m_nVArrowBottomState = keScrollHover;
				m_nVThumbState = keScrollNormal;
				DrawVScrollBar(&dc);
			}
			else if(test == SCROLL_THUMB)
			{
				m_nVArrowTopState = keScrollNormal;
				m_nVArrowBottomState = keScrollNormal;
				m_nVThumbState = keScrollHover;
				DrawVScrollBar(&dc);
			}
			else
			{
				m_nVArrowTopState = keScrollNormal;
				m_nVArrowBottomState = keScrollNormal;
				m_nVThumbState = keScrollNormal;
				DrawVScrollBar(&dc);
			}
			m_nHArrowLeftState = keScrollNormal;
			m_nHArrowRightState = keScrollNormal;
			m_nHThumbState = keScrollNormal;
			if(m_bHScroll)
				DrawHScrollBar(&dc);
		}
		break;
	default:
		Default();
	}
}